#ifndef MATRIXOPERATIONSCPU_H
#define MATRIXOPERATIONSCPU_H

#include <stdexcept>
#include "matrix_operations.h"

class MatrixOperationsCPU : public MatrixOperations {
public:

    // 元素间乘法
    std::vector<std::vector<float>> elementwiseMultiply(const std::vector<std::vector<float>>& matrix1, const std::vector<std::vector<float>>& matrix2) {
        std::vector<std::vector<float>> result(matrix1.size(), std::vector<float>(matrix1[0].size()));
        for (size_t i = 0; i < matrix1.size(); ++i) {
            for (size_t j = 0; j < matrix1[i].size(); ++j) {
                result[i][j] = matrix1[i][j] * matrix2[i][j];
            }
        }
        return result;
    }

    // 矩阵乘法
    std::vector<std::vector<float>> multiply(const std::vector<std::vector<float>>& matA, const std::vector<std::vector<float>>& matB) override {
        size_t rowsA = matA.size();
        size_t colsA = matA[0].size();
        size_t rowsB = matB.size();
        size_t colsB = matB[0].size();
        if (colsA != rowsB) throw std::invalid_argument("Matrix dimensions do not match for multiplication");
        std::vector<std::vector<float>> result(rowsA, std::vector<float>(colsB, 0));
        for (size_t i = 0; i < rowsA; ++i) {
            for (size_t j = 0; j < colsB; ++j) {
                for (size_t k = 0; k < colsA; ++k) {
                    result[i][j] += matA[i][k] * matB[k][j];
                }
            }
        }
        return result;
    }

    // 矩阵转置
    std::vector<std::vector<float>> transpose(const std::vector<std::vector<float>>& mat) override {
        size_t rows = mat.size();
        size_t cols = mat[0].size();
        std::vector<std::vector<float>> result(cols, std::vector<float>(rows));
        for (size_t i = 0; i < rows; ++i) {
            for (size_t j = 0; j < cols; ++j) {
                result[j][i] = mat[i][j];
            }
        }
        return result;
    }

    // 逐元素减法
    std::vector<std::vector<float>> subtract(const std::vector<std::vector<float>>& matrixA, const std::vector<std::vector<float>>& matrixB) {
        if (matrixA.size() != matrixB.size() || matrixA[0].size() != matrixB[0].size()) {
            throw std::invalid_argument("Matrices dimensions do not match for subtraction.");
        }
        size_t numRows = matrixA.size();
        size_t numCols = matrixA[0].size();
        std::vector<std::vector<float>> result(numRows, std::vector<float>(numCols, 0.0));
        for (size_t i = 0; i < numRows; ++i) {
            for (size_t j = 0; j < numCols; ++j) {
                result[i][j] = matrixA[i][j] - matrixB[i][j];
            }
        }
        return result;
    }
};

#endif // MATRIXOPERATIONSCPU_H
